package com.houger.ddd.datamanager.utils;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.houger.ddd.datamanager.entity.InventoryId;
import com.houger.ddd.datamanager.manager.aop.Inventory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.caffeine.CaffeineCacheManager;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CacheUtils {

    private static final String SYSTEM_PREFIX = "java:architect:";

    private static final ConcurrentHashMap<String, Cache> LOCAL_CACHE_MAP = new ConcurrentHashMap<>();

    public static Cache getCacheManager(String group){
        return LOCAL_CACHE_MAP.get(group);
    }

    public static Cache getCacheManager(String group, long expire){
        if(LOCAL_CACHE_MAP.containsKey(group)){
            return LOCAL_CACHE_MAP.get(group);
        }else{
            Cache<String, Object> cache = Caffeine.newBuilder()
                    .initialCapacity(Runtime.getRuntime().availableProcessors() * 4)
                    .maximumSize(10000)
                    .expireAfterWrite(expire, TimeUnit.SECONDS)
                    .build();
            LOCAL_CACHE_MAP.put(group,cache);
            return cache;
        }

    }

    public static String getRedisKey(String group, String key){
        if(StringUtils.isNotEmpty(group)){
            return SYSTEM_PREFIX + group + ":" + key;
        }else{
            return SYSTEM_PREFIX + ":" + key;
        }
    }

    public static String getInventoryTotalKey(Inventory inventory, InventoryId id){
        return CacheUtils.getRedisKey("inventory:"+inventory.value(),id.toString()+":total");
    }

    public static String getInventoryLockKey(Inventory inventory, InventoryId id){
        return CacheUtils.getRedisKey("inventory:"+inventory.value(),id.toString()+":lock");
    }

    public static String getInventoryUsedKey(Inventory inventory, InventoryId id){
        return CacheUtils.getRedisKey("inventory:"+inventory.value(),id.toString()+":used");
    }

    protected static String getInventoryUsedKeyQuery(Inventory inventory){
        return CacheUtils.getRedisKey("inventory:"+inventory.value(),"*:used");
    }

    protected static InventoryId getInventoryUsedKeyId(Inventory inventory,String key){
        String keyPrefix = CacheUtils.getRedisKey("inventory:"+inventory.value(),"");
        key = key.substring(keyPrefix.length(),key.length() - 5);
        return InventoryId.parse(key);
    }

}
